<template>
  <div class="container">
    <canvas ref="canvas" width="640" height="360"></canvas>
    <video ref="video" autoplay loop muted></video>
    <div class="button-group">
      <el-button type="success" @click="startRecording" :disabled="isRecording ||!canRecord">开始录制</el-button>
      <el-button type="primary" @click="toggleRecording" :disabled="!isRecording && recorderState ==='stopped'">
        {{ recorderState === 'paused'? '恢复' : '暂停' }}
      </el-button>
      <el-button type="danger" @click="stopRecording" :disabled="!isRecording">结束录制</el-button>
    </div>
  </div>
</template>

<script>
import { ref, onMounted, onUnmounted } from 'vue';

export default {
  name: 'CameraRecord',
  setup() {
    const canvas = ref(null);
    const video = ref(null);
    const isRecording = ref(false);
    const canRecord = ref(false);
    const chunks = ref([]);

    let frameId = null;
    let recorder = null;
    // 新增变量用于记录录制器的状态（'recording' 录制中，'paused' 暂停中，'stopped' 停止）
    const recorderState = ref('stopped');

    let videoWidth = 848;
    let videoHeight = 480;
    const frameRate = 24; // 调整帧率
    const encodeType = "video/webm;codecs=opus"; // 尝试使用不同的编码格式

    const drawFrame = () => {
      const canvasContext = canvas.value.getContext("2d");
      canvasContext.drawImage(video.value, 0, 0, videoWidth, videoHeight);
      frameId = requestAnimationFrame(drawFrame);
    };

    const startRecording = () => {
      isRecording.value = true;
      canRecord.value = false;
      recorderState.value ='recording';

      // 清空之前的录制数据
      chunks.value = [];

      // 请求音频权限
      navigator.mediaDevices.getUserMedia({
        audio: true,
        video: true
      }).then(mediaStream => {
        video.value.srcObject = mediaStream;
        video.value.play();

        // 获取视频流的实际尺寸
        video.value.addEventListener('loadedmetadata', () => {
          videoWidth = video.value.videoWidth;
          videoHeight = video.value.videoHeight;
          canvas.value.width = videoWidth;
          canvas.value.height = videoHeight;

          // 创建一个新的媒体流，包含视频和音频轨道
          const combinedStream = new MediaStream([...mediaStream.getTracks(),...canvas.value.captureStream(frameRate).getTracks()]);
          recorder = new MediaRecorder(combinedStream, {
            mimeType: encodeType
          });

          recorder.ondataavailable = e => {
            chunks.value.push(e.data);
          };

          recorder.start(10);
          drawFrame();
        });
      }).catch(error => {
        alert("打开摄像头或麦克风失败");
        isRecording.value = false;
        canRecord.value = true;
        recorderState.value ='stopped';
      });
    };

    const stopRecording = () => {
      isRecording.value = false;
      canRecord.value = true;
      recorderState.value ='stopped';
      if (recorder) {
        recorder.stop();
      }
      cancelAnimationFrame(frameId);
      download();

      // 重置状态变量
      chunks.value = [];
      frameId = null;
      recorder = null;

      // 停止媒体流
      if (video.value && video.value.srcObject) {
        const tracks = video.value.srcObject.getTracks();
        tracks.forEach(track => track.stop());
        video.value.srcObject = null;
      }
    };

    const toggleRecording = () => {
      if (recorderState.value ==='recording') {
        recorder.pause();
        recorderState.value = 'paused';
      } else if (recorderState.value === 'paused') {
        recorder.resume();
        recorderState.value ='recording';
      }
    };

    // 上传录制的视频
    async function uploadVideo() {
      if (!videoBlob.value) {
        alert('没有录制视频')
        return
      }

      const formData = new FormData()
      formData.append('video', videoBlob.value, 'recorded-video.webm')

      try {
        const response = await axios.post('http://localhost:8081/api/upload', formData, {
          headers: {
            'Content-Type': 'multipart/form-data',
          },
        })
        console.log('Video uploaded successfully:', response.data)
      } catch (error) {
        console.error('Error uploading video:', error)
        alert('上传视频失败')
      }
    }

    onMounted(() => {
      navigator.mediaDevices.getUserMedia({
        audio: false,
        video: true
      }).then(mediaStream => {
        video.value.srcObject = mediaStream;
        video.value.play();

        // 获取视频流的实际尺寸
        video.value.addEventListener('loadedmetadata', () => {
          videoWidth = video.value.videoWidth;
          videoHeight = video.value.videoHeight;
          canvas.value.width = videoWidth;
          canvas.value.height = videoHeight;

          canRecord.value = true;
        });
      }).catch(error => {
        alert("打开摄像头失败");
      });
    });

    onUnmounted(() => {
      if (recorder && recorder.state!== 'inactive') {
        recorder.stop();
      }
      if (video.value && video.value.srcObject) {
        const tracks = video.value.srcObject.getTracks();
        tracks.forEach(track => track.stop());
        video.value.srcObject = null;
      }
    });

    return {
      canvas,
      video,
      isRecording,
      canRecord,
      startRecording,
      stopRecording,
      toggleRecording,
      recorderState
    };
  },
};
</script>

<style scoped>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
}

canvas {
  display: none;
}

video {
  width: 848px;
  height: 480px;
  background: darkblue;
  display: block;
  border-radius: 2px;
  box-shadow: 0 1px 1.5px 1px rgba(0, 0, 0, 0.12);
  margin-top: -250px;
}

.button-group {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 50px;
  padding: 0 10px;
  width: 600px;
  height: 60px;
}

button {
  width: 150px;
  height: 60px;
  box-sizing: border-box;
  border: none;
  outline: none;
  border-radius: 2px;
  box-shadow: 0 1px 1.5px 1px rgba(0, 0, 0, 0.12);
  user-select: none;
}



button:last-child[disabled] {
  background: gray;
}
</style>